package bsh.meta;

import java.lang.reflect.Modifier;
import java.util.List;

/**
 * Implementation of {@link UnfinishedInnerType}
 * 
 * @author takeshi
 */
public class UnfinishedInnerTypeImpl extends UnfinishedTypeImpl implements UnfinishedInnerType {

    private final FieldDescriptor outerClassInstanceField;

    private final String simpleName;

    private volatile List<String> externalVariables;

    /**
     * Plain constructor
     * 
     * @param sourceCodeName String. May be null
     * @param clName the name of the class
     * @param superType the super type
     * @param ifs the list of implemented interfaces
     * @param outerClass the outer class
     * @param declaringScope the scope that declared the inner class
     * @param modifiers the class modifiers
     * @param simpleName the simple name. May be null for annonymous
     */
    public UnfinishedInnerTypeImpl(String sourceCodeName, String clName, TypeWrapper superType, List<? extends TypeWrapper> ifs,
            UnfinishedType outerClass, Scope declaringScope, int modifiers, String simpleName) {
        super(sourceCodeName, clName, superType, ifs, modifiers);
        this.simpleName = simpleName;
        if (!Modifier.isStatic(modifiers)) {
            this.outerClassInstanceField = this.addField("this$0", outerClass);
        } else {
            this.outerClassInstanceField = null;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String simpleName() {
        return this.simpleName;
    }

    /**
     * {@inheritDoc}
     */
    public FieldDescriptor getEnclosingInstanceField() {
        return this.outerClassInstanceField;
    }

    /**
     * {@inheritDoc}
     */
    public List<String> externalVariables() {
        return getExternalVariables();
    }

    /**
     * @return the externalVariables
     */
    public List<String> getExternalVariables() {
        return externalVariables;
    }

    /**
     * @param externalVariables the externalVariables to set
     */
    public void setExternalVariables(List<String> externalVariables) {
        this.externalVariables = externalVariables;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public TypeWrapper getEnclosingType() {
        return this.outerClassInstanceField.fieldType();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isStatic() {
        return this.outerClassInstanceField == null;
    }

}
